package cn.net.shuxing.yifu.common.service;

import cn.net.shuxing.yifu.common.bean.*;
import cn.net.shuxing.yifu.common.constant.CodeConst;
import cn.net.shuxing.yifu.common.constant.RegistType;
import cn.net.shuxing.yifu.common.constant.UserState;
import cn.net.shuxing.yifu.common.constant.UserType;
import cn.net.shuxing.yifu.common.dto.BaseDto;
import cn.net.shuxing.yifu.common.mapper.UserCapitalMapper;
import cn.net.shuxing.yifu.common.mapper.UserMapper;
import cn.net.shuxing.yifu.common.util.*;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.net.shuxing.yifu.common.util.StringUtils;
import redis.clients.jedis.Jedis;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("commonUserService")
public class UserService extends BaseService<User, UserMapper> {

    @Autowired
    private ShareholderLevelService shareholderLevelService;

    @Autowired
    private UserRealInfoService userRealInfoService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private JedisUtil jedisUtil;

    @Autowired
    private MemberLevelService memberLevelService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserInfoBindService userInfoBindService;

    @Autowired
    private CashWalletService cashWalletService;

    @Autowired
    private AliveCoinActivateHistoryService aliveCoinActivateHistoryService;

    @Autowired
    private UserCapitalMapper userCapitalMapper;

    @Override
    public int insert(User user) {
        String password = user.getPassword();
        user.setPassword(MD5Util.md5(password));
        System.out.println("插入的密码" + MD5Util.md5(password));
        mapper.insertSelective(user);
        return user.getId();
    }

    @Override
    public User getByPrimaryKey(Object key) {
        User user = super.getByPrimaryKey(key);
        if (user == null)
            return null;
        if (user.getType() == UserType.NONE) {
            if (hasRole(user.getId(), UserType.MEMBER)) {
                int userId = user.getId();
                int role = UserType.MEMBER;
                UserRole userRole = userRoleService.getByUserIdAndUserRole(userId, role);
                user.setType(role);
                user.setState(userRole.getState());
                update(user);
                user = super.getByPrimaryKey(key);
            }
        }
        if (user.getType() == UserType.SHAREHOLDER) {
            ShareholderLevel shareholderLevel = shareholderLevelService.getByShareholderId(user.getId());
            Integer level =shareholderLevel.getLevel() ;
            user.setShareholderLevel(level);
            user.setLevel(level);
        }
        return user;
    }

    @Override
    public User getByPrimaryKeyWithoutComplete(Object key) {
        User user = super.getByPrimaryKeyWithoutComplete(key);
        if (user.getType() == UserType.NONE) {
            if (hasRole(user.getId(), UserType.MEMBER)) {
                int userId = user.getId();
                int role = UserType.MEMBER;
                UserRole userRole = userRoleService.getByUserIdAndUserRole(userId, role);
                user.setType(role);
                user.setState(userRole.getState());
                update(user);
                user = super.getByPrimaryKeyWithoutComplete(key);
            }
        }
        return user;
    }

    /**
     * 获取注册时间在lowDate和highDate之间的用户，包含了lowDate和highDate这两天
     *
     * @param lowDate
     * @param highDate
     * @return
     */
    public List<User> searchByRegistDate(LocalDateTime lowDate, LocalDateTime highDate) {
        TimeExample timeExample = new TimeExample(User.class);
        LocalTime localTimeInZero = LocalTimeUtil.createLocalTimeInZero();
        highDate = highDate.plusDays(new Long(1));
        timeExample.between("createTime", lowDate, highDate);
        List<User> userList = mapper.selectByExample(timeExample);

        return userList;

    }

    public User checkUser(String username, String password) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setUsername(username);
        user.setPassword(password);
        return get(user);
    }

    public User checkUser(String username) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setUsername(username);
        return get(user);
    }

    public List<User> searchByRegistDate(LocalDate date) {
        TimeExample timeExample = new TimeExample(User.class);
        LocalTime localTimeInZero = LocalTimeUtil.createLocalTimeInZero();
        LocalDateTime localDateTime = LocalDateTimeUtil.createLocalDateTime(date, localTimeInZero);
        timeExample.equals("createTime", localDateTime);
        List<User> userList = mapper.selectByExample(timeExample);
        return userList;

    }

    public List<User> searchByState(Integer state) {
        CommonExample example = new CommonExample(User.class);
        example.equals("state", state);
        return mapper.selectByExample(example);
    }

    public List<UserCapital> searchByStateInUserCapital(Integer state) {
        CommonExample example = new CommonExample(UserCapital.class);
        example.equals("state", state);
        return userCapitalMapper.selectByExample(example);
    }

    public User insert(String username, String password, Integer registerType) {
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setRegistType(registerType);
        user.setType(UserType.NONE);
        super.insert(user);
        return user;
    }

    public User searchByUsername(String username) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setUsername(username);
        return get(user);
    }

    public User searchByUserid(int userId) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setId(userId);
        return get(user);
    }

    public User update(String username, String password) {
        User user = new User();
        User user1 = searchByUsername(username);
        user1.setPassword(MD5Util.md5(password));
        user1.resetUpdateTime();
        update(user1);
        return user1;
    }

    public List<User> getsByUserType(int userType) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setType(userType);
        return gets(user);
    }

    public String getUserTypeNameByUserId(Integer userId) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setType(userId);
        return get(user).getUserTypeName();

    }

    public Integer getUserTypeByUserId(Integer userId) {
        CommonExample commonExample = new CommonExample(User.class);
        commonExample.equals("id", userId);
        User user = getByExample(commonExample);
        return user.getType();

    }


    public List<User> getsByUserTypeAndUnlock(int userType) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setType(userType);
        user.setState(UserState.OK);
        return gets(user);
    }

    public void activateUser(Integer userId) {
        userRoleService.updateState(userId, UserType.MEMBER, UserState.OK);
        UserRole userRole = userRoleService.getByUserIdAndUserRole(userId, UserType.MEMBER);
        userRole.setLastExamTime(LocalDateTime.now());
        userRoleService.update(userRole);
        User user = getByPrimaryKey(userId);
        if (user.getType() == UserType.MEMBER) {
            user.setState(UserState.OK);
            update(user);
        }
        //Jedis //jedis = jedisUtil.getJedis();
        jedisUtil.set(RedisKeyCreator.shortStartTime(userId), LocalDateTime.now().toString());
        //jedisUtil.close();
        return;
    }

    public BaseDto activateUser(Integer memberId, Integer activateMinutes) {
        BaseDto baseDto = new BaseDto();
        User user = getByPrimaryKey(memberId);
        if (!userRoleService.hasRole(memberId, UserType.NONE)) {
            baseDto.setCode(CodeConst.ERROR);
            baseDto.setMsg("此用户不需要被激活");
        } else {

            boolean flag = userRoleService.updateRole(memberId, UserType.NONE, UserType.MEMBER);
            if (!flag) {
                return BaseDto.error("此用户不需要激活");
            }
//            userRoleService.updateState(memberId,UserType.MEMBER,UserState.ACTIVATING);

            //检查检查
            user.setState(UserState.ACTIVATING);
            update(user);
            /** 初始化现金钱包 **/
            if (cashWalletService.getByPrimaryKey(user.getId()) == null)
                cashWalletService.insert(user.getId(), new BigDecimal(0));
            LocalDateTime activateDateTime = LocalDateTime.now().plusMinutes(Long.valueOf(activateMinutes));
            AliveCoinActivateHistory aliveCoinActivateHistory = aliveCoinActivateHistoryService.getByMemberId(memberId);
            aliveCoinActivateHistory.setActivateTime(activateMinutes);
            aliveCoinActivateHistoryService.update(aliveCoinActivateHistory);
            baseDto.setData("用户激活设置成功,剩余时间为" + activateDateTime.format(DateTimeFormatter.ofPattern("MM-dd HH:mm")));

        }
        return baseDto;
    }

    public List<User> getAllFrozenUser() {
        CommonExample example = new CommonExample(User.class);
        example.equals("state", 1);
        return getsByExampleWithoutComplete(example);
    }

    @Override
    protected void complete(User bean) {
        if (bean == null)
            return;

        Integer level = memberLevelService.calcaulateMemberLevel(bean.getId());
        bean.setLevel(level);
//        if (bean.getType()==UserType.SHAREHOLDER){
//            bean.setUserTypeName("股东");
//        }else if (bean.getType()==UserType.MEMBER){
//            bean.setUserTypeName("会员");
//        }else if (bean.getType()==UserType.BUSINESS){
//            bean.setUserTypeName("商家");
//        }else if (bean.getType()==UserType.NONE){
//            bean.setUserTypeName("会员(未激活)");
//        }else if (bean.getType()==UserType.ADMIN){
//            bean.setUserTypeName("管理员");
//        }
        if (bean.getRegistType() == 0) {
            bean.setPhoneNum(bean.getUsername());
        } else {
            String phoneNum = userInfoBindService.getByPrimaryKey(bean.getId()).getPhoneNum();
            if (StringUtils.hasText(phoneNum)) {
                bean.setPhoneNum(phoneNum);
            } else {
                bean.setPhoneNum("");
            }
        }
    }

    public List<User> getsByUserState(int userState) {
        User user = new User();
        user.clearCreateTimeAndUpdateTime();
        user.setState(userState);
        return gets(user);
    }

    /**
     * 完全无该用户名注册
     **/
    public int regist(User user) {
        int userId = insert(user);
        if (userId > 1) {
            UserInfo userInfo = new UserInfo();
            userInfo.setNickName(user.getUsername());
            userInfo.setId(userId);
            userInfo.setPicture("default.png");
            userInfoService.insert(userInfo);
            /** 添加身份 **/
            addRole(user.getId(), UserType.NONE, UserState.OK);

            /** 添加userInfoBind **/
            UserInfoBind userInfoBind = new UserInfoBind();
            userInfoBind.setId(userId);
            if (user.getRegistType() == RegistType.PHONE)
                userInfoBind.setPhoneNum(user.getUsername());
            if (user.getRegistType() == RegistType.MAIL)
                userInfoBind.setMail(user.getUsername());
            userInfoBindService.insert(userInfoBind);
            /** 初始化现金钱包 **/
            cashWalletService.insert(userId, new BigDecimal(0));
        }
        return userId;
    }

    private void addRole(Integer id, int role, int state) {
        userRoleService.insert(id, role, state);
    }

    public boolean hasRole(Integer id, int userRole) {
        return userRoleService.hasRole(id, userRole);
    }

    public boolean changeRole(Integer userId, int role) {
        if (!checkUser(userId))
            return false;
        if (hasRole(userId, role)) {
            int level = 0 ;

            if (role == UserType.SHAREHOLDER){
                level = shareholderLevelService.getByShareholderId(userId).getLevel();
            }

            if (role == UserType.MEMBER){
                level = memberLevelService.calcaulateMemberLevel(userId);
            }

            UserRole userRole = userRoleService.getByUserIdAndUserRole(userId, role);
            User user = getByPrimaryKey(userId);
            user.setType(role);
            user.setState(userRole.getState());
            user.setLevel(level);
            update(user);
            return true;
        }
        return false;
    }

    public boolean checkUser(Integer userId) {
        return getByPrimaryKey(userId) != null;
    }

    public List<User> getsByList(List<Integer> userIds) {
        CommonExample example = new CommonExample(User.class);
        Example.Criteria criteria = example.getCriteria();
        criteria.andIn("id", userIds);
        return getsByExampleWithoutComplete(example);
    }

    public void updateState(Integer userId, Integer state) {
        User user = getByPrimaryKeyWithoutComplete(userId);
        if (user != null) {
            user.setState(state);
            update(user);
        }
    }

}
